/**
* 作者: LuckKey
* 说明: 只支持64位的内联钩子
* 日期: 2025-03-14
* 版本: 1.0
*/

#pragma once
#include <Windows.h>
#include <iostream>

class InlineHook64 {
public:
	InlineHook64(void* pfSrc, void* pfDst) :m_pfSrc(pfSrc), m_pfDst(pfDst) {
		if (!m_pfSrc || !m_pfDst) {
			throw std::logic_error("InlineHook64 参数不能为空.");
		}
	}

	~InlineHook64() {
		unhook();
	}

	void hook() {
		/*	
			需要12字节：
			mov rax, 地址 = > 0x48 0xb8 + 8字节地址 = 10字节
			push rax = > 0x50 1字节
			ret = > 0xc3 1字节
		*/

		if (!m_isHook) {
			DWORD dwOldProtect = 0;
			VirtualProtect(m_pfSrc, 12, PAGE_EXECUTE_READWRITE, &dwOldProtect);
			memcpy(m_oldData, m_pfSrc, 12);

			BYTE* pFun = (BYTE*)m_pfSrc;
			pFun[0] = 0x48;
			pFun[1] = 0xb8;
			*(ULONGLONG*)(pFun + 2) = (ULONGLONG)m_pfDst;
			pFun[10] = 0x50;
			pFun[11] = 0xc3;
			
			VirtualProtect(m_pfSrc, 12, dwOldProtect, &dwOldProtect);
			m_isHook = true;
		}
	}

	void unhook() {
		if (m_isHook) {
			DWORD dwOldProtect = 0;
			VirtualProtect(m_pfSrc, 12, PAGE_EXECUTE_READWRITE, &dwOldProtect);
			memcpy(m_pfSrc, m_oldData, 12);
			VirtualProtect(m_pfSrc, 12, dwOldProtect, &dwOldProtect);
			m_isHook = false;
		}
	}

private:
	BYTE m_oldData[12]{ };
	void* m_pfSrc;
	void* m_pfDst;
	bool m_isHook = false;
};



